import os
import time
from concurrent.futures import ThreadPoolExecutor

import requests
from Crypto.Cipher import AES


def get_m3u8(url):
    res = requests.get(url)
    with open("../数据暂存/m3u8.txt", "wb") as f:
        f.write(res.content)
    print("m3u8文件下载完成")


def get_key(k):
    #  key : [49, 66, -84, -94, 86, 35, -77, 74, 96, -128, 89, 42, -79, -94, 26, 98]

    with open("../数据暂存/m3u8.txt", "r", encoding='utf-8') as f:
        for line in f:
            line = line.strip()
            if line.startswith('#EXT-X-KEY'):
                iv = line.split('IV=0x')[1]
                print(iv)
                iv = bytes.fromhex(iv)
                break
    key = b''
    for i in k:
        i = i.to_bytes(1, 'little', signed=True)
        key += i
    return key, iv


def dec_ts(key, iv, data):
    """AES解密视频"""
    aes = AES.new(key, IV=iv, mode=AES.MODE_CBC)
    data = aes.decrypt(data)
    return data


def down_ts(url, name, key):
    """下载单个ts文件"""
    name = str(name) + '.ts'
    while True:
        try:
            res = requests.get(url, headers=head, timeout=20)
            with open(f"../数据暂存/{name}", "wb") as f:
                data = res.content
                data = dec_ts(*key, data)
                f.write(data)
            print(f"{name}下载完成")
            # 记录已下载的文件名称
            global lst
            lst.append(name)
            break
        except Exception as e:
            print(f"{name}下载出现异常", e)
            time.sleep(5)


def start_down_ts(key, url):
    list1 = []
    up_url = url.rsplit('/', maxsplit=1)[0]
    with open("../数据暂存/m3u8.txt", "r", encoding="utf-8") as f:
        line: str
        for line in f:
            if line.startswith("#"):
                continue
            ts_url = up_url + '/' + line.strip()
            list1.append(ts_url)
    print(len(list1))
    n = 0
    with ThreadPoolExecutor(25) as t:
        for i in list1:
            n += 1
            t.submit(down_ts, i, n, key)
    print("全部下载完成")


def merge(name):
    """合并ts文件，生成完整的mp4文件"""
    # 获取所有ts文件列表
    global lst
    lst.sort()
    # lst1 = []
    # for i in range(547):
    #     lst1.append(f"{i+1}.ts")
    s = "+".join(lst)
    os.chdir("../数据暂存")
    os.system(f"copy /b {s} {name}")
    os.system(f"move {name} E:\T\Videos\一人之下")
    print("合并成功")
    # 删除暂存数据
    # os.system("del *.ts")
    # os.system("del *.txt")
    print("======Done=====")


def main(url, k, name):
    # 获取m3u8
    get_m3u8(url)
    # 获取密钥
    key = get_key(k)
    # 下载源文件
    start_down_ts(key, url)
    # 视频整合
    merge(name)


if __name__ == '__main__':
    url = 'https://cd11-ccd1-2.play.bokecc.com/flvs/44CACEB725BAB224/2022-06-16/3241AFA15520B04963835A29B2A11961-90.m3u8?t=1673102019&key=B394B6EB7C37656B823078041B29EBC2&tpl=10&tpt=112&custom_id=Z_8985cfec064011edbdcb506b4bfed66c_204993'
    k = [49, 66, -84, -94, 86, 35, -77, 74, 96, -128, 89, 42, -79, -94, 26, 98]
    head = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.54",
        "Referer": "https://xuexi.boxuegu.com/"}
    url1 = 'https://cd15-ccd1-2.play.bokecc.com/flvs/78665FEF083498AB/2022-02-21/B47E504AD3B55E7AF3342D97BB1D6DF8-20.m3u8?t=1673105963&key=A97D516D28E69E92AE3E4CC5F2D9428A&tpl=10&tpt=112'
    k1 = [-73, 125, 83, 73, -48, -74, 93, 121, -16, 55, 46, -108, -72, 30, 110, -5]
    # 定义一个列表，记录ts文件名称
    lst = []
    # 该列表记载两次异常的请求
    t1 = time.time()
    main(url1, k1, "xss案例.mp4")
    t2 = time.time()
    print(f"总耗时{t2 - t1}s")
